﻿using System;
using System.IO;
using System.Text;

namespace RxjhServer.Network
{
	public class PacketReader
	{
		private byte[] m_Data;

		private int m_Size;

		private int m_Index;

		public PacketReader(byte[] data, int size, bool fixedSize)
		{
			this.m_Data = data;
			this.m_Size = size;
			this.m_Index = (fixedSize ? 1 : 3);
		}

		public byte[] Buffer
		{
			get
			{
				return this.m_Data;
			}
		}

		public int Size
		{
			get
			{
				return this.m_Size;
			}
		}

		public void Trace(ClientInfo state)
		{
			try
			{
				using (StreamWriter streamWriter = new StreamWriter("Packets.log", true))
				{
					byte[] data = this.m_Data;
					if (data.Length > 0)
					{
						streamWriter.WriteLine("Client: {0}: Unhandled 包ID 0x{1:X2}{2:X2} 包长{3} 时间{4}", new object[]
						{
							state,
							data[8],
							data[7],
							data.Length,
							DateTime.Now
						});
					}
					using (MemoryStream memoryStream = new MemoryStream(data))
					{
						Utility.FormatBuffer(streamWriter, memoryStream, data.Length);
					}
					streamWriter.WriteLine();
					streamWriter.WriteLine();
				}
			}
			catch
			{
			}
		}

		public int Seek(int offset, SeekOrigin origin)
		{
			switch (origin)
			{
			case SeekOrigin.Begin:
				this.m_Index = offset;
				break;
			case SeekOrigin.Current:
				this.m_Index += offset;
				break;
			case SeekOrigin.End:
				this.m_Index = this.m_Size - offset;
				break;
			}
			return this.m_Index;
		}

		public int ReadInt32()
		{
			if (this.m_Index + 4 > this.m_Size)
			{
				return 0;
			}
			return (int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++] << 16 | (int)this.m_Data[this.m_Index++] << 24;
		}

		public int ReadInt16()
		{
			if (this.m_Index + 2 > this.m_Size)
			{
				return 0;
			}
			return (int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8;
		}

		public int ReadInt8()
		{
			if (this.m_Index + 1 > this.m_Size)
			{
				return 0;
			}
			return (int)this.m_Data[this.m_Index++];
		}

		public float Readfloat()
		{
			if (this.m_Index + 4 > this.m_Size)
			{
				return 0f;
			}
			float result = BitConverter.ToSingle(this.m_Data, this.m_Index);
			this.m_Index += 4;
			return result;
		}

		public uint ReadUInt32()
		{
			if (this.m_Index + 4 > this.m_Size)
			{
				return 0u;
			}
			return (uint)((int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++] << 16 | (int)this.m_Data[this.m_Index++] << 24);
		}

		public ushort ReadUInt16()
		{
			if (this.m_Index + 2 > this.m_Size)
			{
				return 0;
			}
			return (ushort)((int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8);
		}

		public byte ReadByte()
		{
			if (this.m_Index + 1 > this.m_Size)
			{
				return 0;
			}
			return this.m_Data[this.m_Index++];
		}

		public sbyte ReadSByte()
		{
			if (this.m_Index + 1 > this.m_Size)
			{
				return 0;
			}
			return (sbyte)this.m_Data[this.m_Index++];
		}

		public bool ReadBoolean()
		{
			return this.m_Index + 1 <= this.m_Size && this.m_Data[this.m_Index++] != 0;
		}

		public string ReadUnicodeStringLE()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index + 1 < this.m_Size && (num = ((int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8)) != 0)
			{
				stringBuilder.Append((char)num);
			}
			return stringBuilder.ToString();
		}

		public string ReadUnicodeStringLESafe(int fixedLength)
		{
			int num = this.m_Index + (fixedLength << 1);
			int index = num;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num2;
			while (this.m_Index + 1 < num && (num2 = ((int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8)) != 0)
			{
				if (this.IsSafeChar(num2))
				{
					stringBuilder.Append((char)num2);
				}
			}
			this.m_Index = index;
			return stringBuilder.ToString();
		}

		public string ReadUnicodeStringLESafe()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index + 1 < this.m_Size && (num = ((int)this.m_Data[this.m_Index++] | (int)this.m_Data[this.m_Index++] << 8)) != 0)
			{
				if (this.IsSafeChar(num))
				{
					stringBuilder.Append((char)num);
				}
			}
			return stringBuilder.ToString();
		}

		public string ReadUnicodeStringSafe()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index + 1 < this.m_Size && (num = ((int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++])) != 0)
			{
				if (this.IsSafeChar(num))
				{
					stringBuilder.Append((char)num);
				}
			}
			return stringBuilder.ToString();
		}

		public string ReadUnicodeString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index + 1 < this.m_Size && (num = ((int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++])) != 0)
			{
				stringBuilder.Append((char)num);
			}
			return stringBuilder.ToString();
		}

		public bool IsSafeChar(int c)
		{
			return c >= 32 && c < 65534;
		}

		public string ReadUTF8StringSafe(int fixedLength)
		{
			if (this.m_Index >= this.m_Size)
			{
				this.m_Index += fixedLength;
				return string.Empty;
			}
			int num = this.m_Index + fixedLength;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			int num2 = 0;
			int num3 = this.m_Index;
			int index = this.m_Index;
			while (num3 < num && this.m_Data[num3++] != 0)
			{
				num2++;
			}
			num3 = 0;
			byte[] array = new byte[num2];
			int num4;
			while (this.m_Index < num && (num4 = (int)this.m_Data[this.m_Index++]) != 0)
			{
				array[num3++] = (byte)num4;
			}
			string @string = Utility.UTF8.GetString(array);
			bool flag = true;
			int num5 = 0;
			while (flag && num5 < @string.Length)
			{
				flag = this.IsSafeChar((int)@string[num5]);
				num5++;
			}
			this.m_Index = index + fixedLength;
			if (flag)
			{
				return @string;
			}
			StringBuilder stringBuilder = new StringBuilder(@string.Length);
			for (int i = 0; i < @string.Length; i++)
			{
				if (this.IsSafeChar((int)@string[i]))
				{
					stringBuilder.Append(@string[i]);
				}
			}
			return stringBuilder.ToString();
		}

		public string ReadUTF8StringSafe()
		{
			if (this.m_Index >= this.m_Size)
			{
				return string.Empty;
			}
			int num = 0;
			int num2 = this.m_Index;
			while (num2 < this.m_Size && this.m_Data[num2++] != 0)
			{
				num++;
			}
			num2 = 0;
			byte[] array = new byte[num];
			int num3;
			while (this.m_Index < this.m_Size && (num3 = (int)this.m_Data[this.m_Index++]) != 0)
			{
				array[num2++] = (byte)num3;
			}
			string @string = Utility.UTF8.GetString(array);
			bool flag = true;
			int num4 = 0;
			while (flag && num4 < @string.Length)
			{
				flag = this.IsSafeChar((int)@string[num4]);
				num4++;
			}
			if (flag)
			{
				return @string;
			}
			StringBuilder stringBuilder = new StringBuilder(@string.Length);
			for (int i = 0; i < @string.Length; i++)
			{
				if (this.IsSafeChar((int)@string[i]))
				{
					stringBuilder.Append(@string[i]);
				}
			}
			return stringBuilder.ToString();
		}

		public string ReadUTF8String()
		{
			if (this.m_Index >= this.m_Size)
			{
				return string.Empty;
			}
			int num = 0;
			int num2 = this.m_Index;
			while (num2 < this.m_Size && this.m_Data[num2++] != 0)
			{
				num++;
			}
			num2 = 0;
			byte[] array = new byte[num];
			int num3;
			while (this.m_Index < this.m_Size && (num3 = (int)this.m_Data[this.m_Index++]) != 0)
			{
				array[num2++] = (byte)num3;
			}
			return Utility.UTF8.GetString(array);
		}

		public string ReadString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index < this.m_Size && (num = (int)this.m_Data[this.m_Index++]) != 0)
			{
				stringBuilder.Append((char)num);
			}
			return stringBuilder.ToString();
		}

		public string ReadStringSafe()
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			while (this.m_Index < this.m_Size && (num = (int)this.m_Data[this.m_Index++]) != 0)
			{
				if (this.IsSafeChar(num))
				{
					stringBuilder.Append((char)num);
				}
			}
			return stringBuilder.ToString();
		}

		public string ReadUnicodeStringSafe(int fixedLength)
		{
			int num = this.m_Index + (fixedLength << 1);
			int index = num;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num2;
			while (this.m_Index + 1 < num && (num2 = ((int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++])) != 0)
			{
				if (this.IsSafeChar(num2))
				{
					stringBuilder.Append((char)num2);
				}
			}
			this.m_Index = index;
			return stringBuilder.ToString();
		}

		public string ReadUnicodeString(int fixedLength)
		{
			int num = this.m_Index + (fixedLength << 1);
			int index = num;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num2;
			while (this.m_Index + 1 < num && (num2 = ((int)this.m_Data[this.m_Index++] << 8 | (int)this.m_Data[this.m_Index++])) != 0)
			{
				stringBuilder.Append((char)num2);
			}
			this.m_Index = index;
			return stringBuilder.ToString();
		}

		public string ReadStringSafe(int fixedLength)
		{
			int num = this.m_Index + fixedLength;
			int index = num;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num2;
			while (this.m_Index < num && (num2 = (int)this.m_Data[this.m_Index++]) != 0)
			{
				if (this.IsSafeChar(num2))
				{
					stringBuilder.Append((char)num2);
				}
			}
			this.m_Index = index;
			return stringBuilder.ToString();
		}

		public string ReadString(int fixedLength)
		{
			int num = this.m_Index + fixedLength;
			int index = num;
			if (num > this.m_Size)
			{
				num = this.m_Size;
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num2;
			while (this.m_Index < num && (num2 = (int)this.m_Data[this.m_Index++]) != 0)
			{
				stringBuilder.Append((char)num2);
			}
			this.m_Index = index;
			return stringBuilder.ToString();
		}
	}
}
